/**
 * 消息管理器 - 内存优化版本
 */

import { memoryManager, performanceMonitor } from './performance.js';

export class MessageManager {
  constructor(options = {}) {
    this.options = {
      maxMessages: 1000,           // 最大消息数量
      cleanupThreshold: 500,       // 清理阈值
      cleanupInterval: 30000,      // 清理间隔（30秒）
      enableCompression: true,     // 启用压缩
      enableLazyLoad: true,        // 启用懒加载
      ...options
    };
    
    this.messages = new Map();
    this.messageIndex = [];
    this.compressedMessages = new Map();
    this.cleanupTimer = null;
    this.isCompressing = false;
    
    this.startCleanup();
  }
  
  // 添加消息
  addMessage(message) {
    const messageId = message.id || message.tempId || this.generateId();
    
    // 检查是否超过最大数量
    if (this.messages.size >= this.options.maxMessages) {
      this.cleanupOldMessages();
    }
    
    // 存储消息
    this.messages.set(messageId, {
      ...message,
      id: messageId,
      timestamp: Date.now(),
      accessCount: 0
    });
    
    // 更新索引
    this.updateIndex(messageId, message);
    
    // 性能监控
    performanceMonitor.incrementCounter('messageCount');
    
    return messageId;
  }
  
  // 获取消息
  getMessage(messageId) {
    const message = this.messages.get(messageId);
    if (message) {
      message.accessCount++;
      message.lastAccess = Date.now();
      return message;
    }
    
    // 尝试从压缩存储中获取
    if (this.options.enableCompression) {
      return this.getCompressedMessage(messageId);
    }
    
    return null;
  }
  
  // 获取消息列表
  getMessages(startIndex = 0, count = 50) {
    const endIndex = Math.min(startIndex + count, this.messageIndex.length);
    const result = [];
    
    for (let i = startIndex; i < endIndex; i++) {
      const messageId = this.messageIndex[i];
      const message = this.getMessage(messageId);
      if (message) {
        result.push(message);
      }
    }
    
    return result;
  }
  
  // 更新消息
  updateMessage(messageId, updates) {
    const message = this.messages.get(messageId);
    if (message) {
      Object.assign(message, updates, {
        lastModified: Date.now()
      });
      return true;
    }
    return false;
  }
  
  // 删除消息
  deleteMessage(messageId) {
    const deleted = this.messages.delete(messageId);
    if (deleted) {
      this.removeFromIndex(messageId);
    }
    return deleted;
  }
  
  // 清理旧消息
  cleanupOldMessages() {
    if (this.isCompressing) return;
    
    const messagesToCompress = [];
    const now = Date.now();
    
    // 找出需要压缩的消息（超过5分钟未访问）
    for (const [id, message] of this.messages.entries()) {
      if (now - message.lastAccess > 300000) { // 5分钟
        messagesToCompress.push({ id, message });
      }
    }
    
    // 压缩消息
    if (messagesToCompress.length > 0) {
      this.compressMessages(messagesToCompress);
    }
    
    // 如果还是太多，删除最旧的消息
    if (this.messages.size > this.options.maxMessages) {
      this.deleteOldestMessages();
    }
  }
  
  // 压缩消息
  compressMessages(messagesToCompress) {
    this.isCompressing = true;
    
    try {
      messagesToCompress.forEach(({ id, message }) => {
        // 压缩消息数据
        const compressed = this.compressMessage(message);
        this.compressedMessages.set(id, compressed);
        
        // 从内存中移除
        this.messages.delete(id);
      });
      
      // 更新内存使用统计
      this.updateMemoryStats();
      
    } finally {
      this.isCompressing = false;
    }
  }
  
  // 压缩单个消息
  compressMessage(message) {
    const compressed = {
      id: message.id,
      timestamp: message.timestamp,
      messageType: message.messageType,
      content: message.content,
      isMyselfMsg: message.isMyselfMsg,
      othersUserId: message.othersUserId,
      othersAvatar: message.othersAvatar,
      othersRemark: message.othersRemark,
      myNickName: message.myNickName,
      myAvatar: message.myAvatar,
      createTime: message.createTime
    };
    
    // 移除不必要的数据
    delete compressed.accessCount;
    delete compressed.lastAccess;
    delete compressed.lastModified;
    
    return compressed;
  }
  
  // 从压缩存储获取消息
  getCompressedMessage(messageId) {
    const compressed = this.compressedMessages.get(messageId);
    if (compressed) {
      // 解压缩消息
      const message = this.decompressMessage(compressed);
      
      // 重新加载到内存
      this.messages.set(messageId, message);
      
      return message;
    }
    
    return null;
  }
  
  // 解压缩消息
  decompressMessage(compressed) {
    return {
      ...compressed,
      accessCount: 0,
      lastAccess: Date.now()
    };
  }
  
  // 删除最旧的消息
  deleteOldestMessages() {
    const messagesArray = Array.from(this.messages.entries());
    messagesArray.sort((a, b) => a[1].lastAccess - b[1].lastAccess);
    
    const toDelete = messagesArray.slice(0, 100); // 删除最旧的100条
    toDelete.forEach(([id]) => {
      this.messages.delete(id);
      this.removeFromIndex(id);
    });
  }
  
  // 更新索引
  updateIndex(messageId, message) {
    const index = this.messageIndex.indexOf(messageId);
    if (index === -1) {
      // 按时间排序插入
      const insertIndex = this.findInsertIndex(message.createTime);
      this.messageIndex.splice(insertIndex, 0, messageId);
    }
  }
  
  // 从索引中移除
  removeFromIndex(messageId) {
    const index = this.messageIndex.indexOf(messageId);
    if (index !== -1) {
      this.messageIndex.splice(index, 1);
    }
  }
  
  // 查找插入位置
  findInsertIndex(createTime) {
    let left = 0;
    let right = this.messageIndex.length;
    
    while (left < right) {
      const mid = Math.floor((left + right) / 2);
      const midMessage = this.messages.get(this.messageIndex[mid]);
      
      if (midMessage && midMessage.createTime < createTime) {
        left = mid + 1;
      } else {
        right = mid;
      }
    }
    
    return left;
  }
  
  // 生成ID
  generateId() {
    return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }
  
  // 开始清理定时器
  startCleanup() {
    this.cleanupTimer = setInterval(() => {
      this.cleanupOldMessages();
    }, this.options.cleanupInterval);
  }
  
  // 停止清理定时器
  stopCleanup() {
    if (this.cleanupTimer) {
      clearInterval(this.cleanupTimer);
      this.cleanupTimer = null;
    }
  }
  
  // 更新内存统计
  updateMemoryStats() {
    const stats = {
      activeMessages: this.messages.size,
      compressedMessages: this.compressedMessages.size,
      totalMessages: this.messageIndex.length,
      memoryUsage: this.estimateMemoryUsage()
    };
    
    // 发送到性能监控
    performanceMonitor.updateMemoryUsage();
    
    return stats;
  }
  
  // 估算内存使用
  estimateMemoryUsage() {
    let totalSize = 0;
    
    // 计算活跃消息内存
    for (const message of this.messages.values()) {
      totalSize += this.estimateObjectSize(message);
    }
    
    // 计算压缩消息内存
    for (const message of this.compressedMessages.values()) {
      totalSize += this.estimateObjectSize(message);
    }
    
    return Math.round(totalSize / 1024); // KB
  }
  
  // 估算对象大小
  estimateObjectSize(obj) {
    let size = 0;
    
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        size += key.length * 2; // 键名大小
        
        const value = obj[key];
        if (typeof value === 'string') {
          size += value.length * 2; // 字符串大小
        } else if (typeof value === 'number') {
          size += 8; // 数字大小
        } else if (typeof value === 'boolean') {
          size += 4; // 布尔值大小
        } else if (typeof value === 'object' && value !== null) {
          size += this.estimateObjectSize(value); // 递归计算
        }
      }
    }
    
    return size;
  }
  
  // 获取统计信息
  getStats() {
    return {
      totalMessages: this.messageIndex.length,
      activeMessages: this.messages.size,
      compressedMessages: this.compressedMessages.size,
      memoryUsage: this.estimateMemoryUsage(),
      options: this.options
    };
  }
  
  // 清空所有消息
  clear() {
    this.messages.clear();
    this.messageIndex = [];
    this.compressedMessages.clear();
  }
  
  // 销毁管理器
  destroy() {
    this.stopCleanup();
    this.clear();
  }
}

// 消息缓存管理器
export class MessageCacheManager {
  constructor() {
    this.cache = new Map();
    this.maxSize = 500;
    this.ttl = 300000; // 5分钟
  }
  
  set(key, value) {
    if (this.cache.size >= this.maxSize) {
      this.evictOldest();
    }
    
    this.cache.set(key, {
      value,
      timestamp: Date.now()
    });
  }
  
  get(key) {
    const item = this.cache.get(key);
    if (item) {
      if (Date.now() - item.timestamp > this.ttl) {
        this.cache.delete(key);
        return null;
      }
      return item.value;
    }
    return null;
  }
  
  evictOldest() {
    let oldestKey = null;
    let oldestTime = Date.now();
    
    for (const [key, item] of this.cache.entries()) {
      if (item.timestamp < oldestTime) {
        oldestTime = item.timestamp;
        oldestKey = key;
      }
    }
    
    if (oldestKey) {
      this.cache.delete(oldestKey);
    }
  }
  
  clear() {
    this.cache.clear();
  }
}

// 导出单例实例
export const messageManager = new MessageManager();
export const messageCacheManager = new MessageCacheManager();
